Setup
-
Install Go :
-
Init the module :
-
go mod init <project_name>
-
-
Install Raylib :
-
go get github.com/gen2brain/raylib-go/raylib
-
-
Get the latest RayLib release :
-
The
.dllis required to be placed at in the same folder as themain.go, or in the PATH .
-
File System :
. ├── raylib.dll // the downloaded raylib .dll ├── main.go ├── go.sum // file created when installing dependencies. └── go.mod // file created when initializing the module. -
Execute :
-
go run main.go
-
Moving Ball
/*
go run main.go
*/
package main
import (
"github.com/gen2brain/raylib-go/raylib"
)
func main() {
const SCREEN_WIDTH = 800
const SCREEN_HEIGHT = 450
rl.InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Raylib in Go | 1_moving_ball")
rl.SetTargetFPS(60)
// Initialize ball
ball_position := rl.Vector2{X: SCREEN_WIDTH / 2.0, Y: SCREEN_HEIGHT / 2.0}
for !rl.WindowShouldClose() {
// Update ball position
if rl.IsKeyDown(rl.KeyRight) {
ball_position.X += 2.0
}
if rl.IsKeyDown(rl.KeyLeft) {
ball_position.X -= 2.0
}
if rl.IsKeyDown(rl.KeyUp) {
ball_position.Y -= 2.0
}
if rl.IsKeyDown(rl.KeyDown) {
ball_position.Y += 2.0
}
// Draw
rl.BeginDrawing()
rl.ClearBackground(rl.RayWhite)
rl.DrawText("move the ball with arrow keys", 10, 10, 20, rl.DarkGray)
rl.DrawCircleV(ball_position, 50.0, rl.Maroon)
rl.EndDrawing()
}
rl.CloseWindow()
}
Collect The Coins
/*
go run main.go
*/
package main
import (
"fmt"
"math/rand"
"time"
rl "github.com/gen2brain/raylib-go/raylib"
)
const (
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
MAX_COINS = 20
PLAYER_SPEED = 4.0
)
type Player struct {
position rl.Vector2
radius float32
score int
}
type Coin struct {
position rl.Vector2
radius float32
active bool
}
func main() {
rl.InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Raylib in Go | 2_collect_the_coins")
rl.SetTargetFPS(60)
defer rl.CloseWindow()
// Seed random generator
rand.Seed(time.Now().UnixNano())
// Initialize player
player := Player{
position: rl.NewVector2(SCREEN_WIDTH/2, SCREEN_HEIGHT/2),
radius: 20,
score: 0,
}
// Initialize coins
var coins [MAX_COINS]Coin
for i := 0; i < MAX_COINS; i++ {
coins[i] = Coin{
position: rl.NewVector2(float32(rand.Intn(SCREEN_WIDTH-40)+20), float32(rand.Intn(SCREEN_HEIGHT-40)+20)),
radius: 8,
active: true,
}
}
// Main game loop
for !rl.WindowShouldClose() {
// Update player
if rl.IsKeyDown(rl.KeyW) {
player.position.Y -= PLAYER_SPEED
}
if rl.IsKeyDown(rl.KeyS) {
player.position.Y += PLAYER_SPEED
}
if rl.IsKeyDown(rl.KeyA) {
player.position.X -= PLAYER_SPEED
}
if rl.IsKeyDown(rl.KeyD) {
player.position.X += PLAYER_SPEED
}
// Check collisions
for i := 0; i < MAX_COINS; i++ {
if coins[i].active {
dist := rl.Vector2Distance(player.position, coins[i].position)
if dist < player.radius+coins[i].radius {
coins[i].active = false
player.score++
}
}
}
// Draw
rl.BeginDrawing()
rl.ClearBackground(rl.DarkGreen)
rl.DrawCircleV(player.position, player.radius, rl.Blue)
for i := 0; i < MAX_COINS; i++ {
if coins[i].active {
rl.DrawCircleV(coins[i].position, coins[i].radius, rl.Gold)
}
}
rl.DrawText(fmt.Sprintf("Score: %d", player.score), 10, 10, 20, rl.White)
rl.EndDrawing()
}
}
Space Invaders
/*
go run main.go
*/
package main
import (
"fmt"
"math/rand"
"time"
rl "github.com/gen2brain/raylib-go/raylib"
)
const (
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
MAX_BULLETS = 64
BULLET_SPEED = 6.0
)
type Player struct {
Position rl.Vector2
Radius float32
}
type Bullet struct {
Position rl.Vector2
Velocity rl.Vector2
Radius float32
Active bool
}
type Enemy struct {
Position rl.Vector2
Radius float32
Active bool
Color rl.Color
}
func spawnBullet(bullets []Bullet, pos rl.Vector2) {
for i := range bullets {
if !bullets[i].Active {
bullets[i].Active = true
bullets[i].Position = pos
bullets[i].Velocity = rl.Vector2{X: 0, Y: -BULLET_SPEED}
bullets[i].Radius = 5
return
}
}
}
func spawnInactiveEnemies(enemies []Enemy) {
for i := range enemies {
if !enemies[i].Active {
enemies[i].Position = rl.Vector2{
X: float32(rand.Intn(701) + 50),
Y: float32(rand.Intn(251) + 50),
}
enemies[i].Radius = 15
enemies[i].Active = true
enemies[i].Color = rl.NewColor(
uint8(rand.Intn(156)+100),
uint8(rand.Intn(156)+100),
uint8(rand.Intn(156)+100),
255,
)
}
}
}
func main() {
rand.Seed(time.Now().UnixNano())
rl.InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Raylib in Go | 3_space_invaders")
rl.SetTargetFPS(60)
player := Player{Position: rl.Vector2{X: 400, Y: 500}, Radius: 20}
var bullets [MAX_BULLETS]Bullet // Stack allocation.
enemiesCount := 20
enemies := make([]Enemy, enemiesCount) // Heap allocation.
// No need to free this, as there's Go is garbage collected. You can't manually free it.
enemiesDestroyedCount := 0
spawnInactiveEnemies(enemies)
for !rl.WindowShouldClose() {
// Player movement
if rl.IsKeyDown(rl.KeyA) {
player.Position.X -= 4
}
if rl.IsKeyDown(rl.KeyD) {
player.Position.X += 4
}
if rl.IsKeyDown(rl.KeyW) {
player.Position.Y -= 4
}
if rl.IsKeyDown(rl.KeyS) {
player.Position.Y += 4
}
if rl.IsKeyPressed(rl.KeySpace) {
spawnBullet(bullets[:], player.Position)
}
// Update bullets
for i := range bullets {
if bullets[i].Active {
bullets[i].Position.X += bullets[i].Velocity.X
bullets[i].Position.Y += bullets[i].Velocity.Y
if bullets[i].Position.Y < 0 {
bullets[i].Active = false
}
}
}
// Update enemies
activeEnemies := 0
for i := range enemies {
if enemies[i].Active {
enemies[i].Position.Y += 0.5
activeEnemies++
}
}
// Respawn inactive enemies if too few
if activeEnemies < 5 {
spawnInactiveEnemies(enemies)
}
// Check collisions
for i := range bullets {
if !bullets[i].Active {
continue
}
for j := range enemies {
if !enemies[j].Active {
continue
}
d := rl.Vector2Distance(bullets[i].Position, enemies[j].Position)
r := bullets[i].Radius + enemies[j].Radius
if d < r {
bullets[i].Active = false
enemies[j].Active = false
enemiesDestroyedCount++
}
}
}
// Drawing
rl.BeginDrawing()
rl.ClearBackground(rl.Black)
rl.DrawCircleV(player.Position, player.Radius, rl.Blue)
for i := range bullets {
if bullets[i].Active {
rl.DrawCircleV(bullets[i].Position, bullets[i].Radius, rl.Yellow)
}
}
for i := range enemies {
if enemies[i].Active {
rl.DrawCircleV(enemies[i].Position, enemies[i].Radius, enemies[i].Color)
}
}
rl.DrawText("Space Invaders: WASD move | SPACE shoot", 10, 10, 20, rl.White)
rl.DrawText(fmt.Sprintf("Enemies destroyed: %d", enemiesDestroyedCount), 10, 40, 20, rl.Yellow)
rl.EndDrawing()
}
rl.CloseWindow()
}